package com.feishi.core.media.opencv;

/**
 * @version 1.0
 * @auth caixq
 * @time 18-4-20 17:16
 **/
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

import com.feishi.core.media.opencv.util.OpenCvUtil;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import org.opencv.videoio.VideoCapture;

public class CameraBasic {

    static {
        OpenCvUtil.loadLibrary();
//        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    private JFrame frame;
    static JLabel label;
    static int flag = 0;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            try {
                CameraBasic window = new CameraBasic();
                window.frame.setVisible(true);

            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        VideoCapture camera = new VideoCapture();
        camera.open(0);
        if (!camera.isOpened()) {
            System.out.println("Camera Error");
        } else {
            Mat frame = new Mat();
            Mat firstFrame = null;

            while (flag == 0) {
                camera.read(frame);

                // 捕捉动态
                Imgproc.resize(frame, frame, new Size(500, 500));
                Mat gray = new Mat();
                Imgproc.cvtColor(frame, gray, Imgproc.COLOR_BGR2GRAY);
                Imgproc.GaussianBlur(gray, gray, new Size(21, 21), 0);

                if (firstFrame == null) {
                    firstFrame = gray;
                    continue;
                }

                Mat frameDelta = new Mat();
                Core.absdiff(firstFrame, gray, frameDelta);
                Mat thresh = new Mat();
                Imgproc.threshold(frameDelta, thresh, 25, 255, Imgproc.THRESH_BINARY);

                List<MatOfPoint> contours = new ArrayList<>();
                Mat hierarchy = new Mat();

                Imgproc.findContours(thresh, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
                Imgproc.dilate(thresh, thresh, new Mat(), new Point(-1, -1), 2);

                for (MatOfPoint mf : contours) {

                    if (Imgproc.contourArea(mf) < 2000) {
                        continue;
                    }
                    Imgproc.drawContours(frame, contours, contours.indexOf(mf), new Scalar(0, 255, 255));
                    Imgproc.fillConvexPoly(frame, mf, new Scalar(0, 255, 255));
                    Rect r = Imgproc.boundingRect(mf);
                    Imgproc.rectangle(frame, r.tl(), r.br(), new Scalar(0, 255, 0), 2);
                }
                firstFrame = gray;

                label.setIcon(new ImageIcon(matToBufferedImage(frame)));
                try {
                    Thread.sleep(40);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * Create the application.
     */
    public CameraBasic() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 800, 450);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);

        JButton btnNewButton = new JButton("\u62CD\u7167");
        btnNewButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                flag = 1;
            }
        });
        btnNewButton.setBounds(33, 13, 113, 27);
        frame.getContentPane().add(btnNewButton);

        label = new JLabel("");
        label.setBounds(0, 0, 800, 450);
        frame.getContentPane().add(label);
    }

    public static BufferedImage matToBufferedImage(Mat mat) {
        if (mat.height() > 0 && mat.width() > 0) {
            BufferedImage image = new BufferedImage(mat.width(), mat.height(), BufferedImage.TYPE_3BYTE_BGR);
            WritableRaster raster = image.getRaster();
            DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
            byte[] data = dataBuffer.getData();
            mat.get(0, 0, data);
            return image;
        }

        return null;
    }
}
